package com.daveclay.boilermaker.web.resteasy

import com.google.inject._
import org.jboss.resteasy.plugins.guice.GuiceResourceFactory
import org.jboss.resteasy.spi.Registry
import org.jboss.resteasy.spi.ResteasyProviderFactory
import org.jboss.resteasy.util.GetRestful
import javax.ws.rs.ext.Provider
import scala.collection.JavaConversions._
import org.slf4j.LoggerFactory

class ModuleProcessor(registry: Registry, providerFactory: ResteasyProviderFactory) {
    val logger = LoggerFactory.getLogger(classOf[ModuleProcessor])

    def process(modules: Module*) = {
        val injector = Guice.createInjector(modules)
        processInjector(injector)
        injector
    }

    private def processInjector(injector: Injector) {
        for (binding <- injector.getBindings.values) {
            val `type` = binding.getKey.getTypeLiteral.getType
            if (`type`.isInstanceOf[Class[_]]) {
                val beanClass = `type`.asInstanceOf[Class[_]]
                if (GetRestful.isRootResource(beanClass)) {
                    val resourceFactory = new GuiceResourceFactory(binding.getProvider, beanClass)
                    logger.info("registering factory for " + beanClass.getName)
                    registry.addResourceFactory(resourceFactory)
                }
                if (beanClass.isAnnotationPresent(classOf[Provider])) {
                    logger.info("registering provider instance for " + beanClass.getName)
                    providerFactory.registerProviderInstance(binding.getProvider.get)
                }
            }
        }
    }
}